// Copyright (C)2012 Johann Duscher. All rights reserved.
//
// This file is part of QwTAPI.
//
// QwTAPI is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// QwTAPI is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with QwTAPI.  If not, see <http://www.gnu.org/licenses/>.

#include "Call.h"

#include "Connection.h"
#include "Line.h"
#include "Request.h"


namespace qwtapi
{

Call::Call(Line *pLine, HCALL hCall)
    : super(pLine),
      m_hCall(hCall),
      m_callInfo(hCall),
      m_callStatus(hCall)
{
    qDebug() << Q_FUNC_INFO << pLine << hCall;
    Q_ASSERT(pLine);
    Q_ASSERT(NULL != hCall);
}

Call::~Call()
{
    qDebug() << Q_FUNC_INFO << getLine() << m_hCall;
}

LONG Call::deallocate()
{
    Q_ASSERT(getCallHandle());

    LONG errCode = lineDeallocateCall(getCallHandle());
    qDebug() << Q_FUNC_INFO << m_hCall << toString(errCode);
    if (NULL == errCode)
        m_hCall = NULL;

    return errCode;
}

LONG Call::drop(const QString& userUserInfo)
{
    QScopedPointer<Request> spRequest(getLine()->getConnection()->createRequest(this, SLOT(onDropResult(const Request*))));
    spRequest->callHandle() = m_hCall;
    std::string userToUserStd = userUserInfo.toStdString();
    LONG result = lineDrop(getCallHandle(), userToUserStd.empty() ? NULL : userToUserStd.c_str(), userToUserStd.length());
    qDebug() << Q_FUNC_INFO << m_hCall << toString(result);
    if (result >= 0)
        getLine()->getConnection()->addRequest(spRequest.take(), lineDrop, result);

    return result;
}

void Call::onDropResult(const Request* pRequest)
{
    Q_ASSERT(lineDrop == pRequest->getRequestType());

    qDebug() << Q_FUNC_INFO << pRequest->callHandle() << "Drop result:" << pRequest->getResult();
}

LONG Call::accept(const QString& userToUser)
{
    QScopedPointer<Request> spRequest(getLine()->getConnection()->createRequest(this, SLOT(onAcceptResult(const Request*))));
    spRequest->callHandle() = m_hCall;
    std::string userToUserStd = userToUser.toStdString();
    LONG result = lineAccept(getCallHandle(), userToUserStd.empty() ? NULL : userToUserStd.c_str(), userToUserStd.length());
    qDebug() << Q_FUNC_INFO << m_hCall << toString(result);
    if (result >= 0)
        getLine()->getConnection()->addRequest(spRequest.take(), lineAccept, result);

    return result;
}

void Call::onAcceptResult(const Request* pRequest)
{
    Q_ASSERT(lineAccept == pRequest->getRequestType());

    qDebug() << Q_FUNC_INFO << pRequest->callHandle() << "Accept result:" << pRequest->getResult();
}

void Call::initialize()
{
    qDebug() << Q_FUNC_INFO << getLine();
}

Line* Call::getLine() const
{
    return static_cast<Line*>(parent());
}

HCALL Call::getCallHandle() const
{
    return m_hCall;
}

const CallInfo& Call::getCallInfo(LONG* pResult) const
{
    LONG result = m_callInfo.refresh();
    if (pResult)
        *pResult = result;

    return m_callInfo;
}

const CallStatus& Call::getCallStatus(LONG* pResult) const
{
    LONG result = m_callStatus.refresh();
    if (pResult)
        *pResult = result;

    return m_callStatus;
}

Address* Call::getAddress(LONG* pResult) const
{
    const CallInfo& ci = getCallInfo(pResult);

    return ci.isValid() ? getLine()->getAddressFromId(ci.getAddressId()) : NULL;
}

LONG Call::setPrivilege(CallPrivilege::Constant callPrivilege)
{
    return lineSetCallPrivilege(m_hCall, callPrivilege);
}

LONG Call::setMediaMode(MediaMode::Constants mediaModes)
{
    return lineSetMediaMode(m_hCall, mediaModes);
}

}
